package cn.aitstone.basic.service.impl;

import cn.aitstone.basic.constant.BaseConstants;
import cn.aitstone.basic.dto.SmsCodeDto;
import cn.aitstone.basic.dto.EmailCodeDto;
import cn.aitstone.basic.exception.BusinessException;
import cn.aitstone.basic.service.IVerifyCodeService;
import cn.aitstone.basic.utils.StrUtils;
import cn.aitstone.basic.utils.VerifyCodeUtils;
import cn.aitstone.user.domain.User;
import cn.aitstone.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String graph(String imageCodeKey) {
        if (StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("参数不能为空，请输入！");
        }
        String str = StrUtils.getComplexRandomString(4);
        redisTemplate.opsForValue().set(imageCodeKey, str, 5, TimeUnit.MINUTES);
        String imgeBase64Str = VerifyCodeUtils.VerifyCode(100, 30, str);
        return imgeBase64Str;


    }

    @Override
    public void smsCode(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        String type = smsCodeDto.getType();
        // 参数校验
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)){
            throw new BusinessException("参数不能为空！");
        }
        if("register".equals(type)){
            checkImageCode(smsCodeDto);
            // 根据电话号码查询该用户
            User user = userMapper.loadByPhone(phone);
            if(user != null){
                throw new BusinessException("用户已存在，请直接登录");
            }
            sendCode(BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY, phone);
        } else if("binder".equals(type)){
            sendCode(BaseConstants.VerifyCodeConstant.BUSINESS_BINDER_KEY, phone);
        }

    }



    /**
    * @Title: checkImageCode
    * @Description: 校验图形验证码方法
    * @Author: Sheldon
    * @Version: 1.0
    * @Date:  2022/7/10 18:42  
    * @Parameters: [smsCodeDto]
    * @Return void
    */
    public void checkImageCode(SmsCodeDto smsCodeDto){
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        String imageCodeValue = smsCodeDto.getImageCodeValue();
        Object imageCodeKeyTemp = redisTemplate.opsForValue().get(imageCodeKey);
        if (StringUtils.isEmpty(imageCodeKey) || StringUtils.isEmpty(imageCodeValue)){
            throw new BusinessException("参数不能为空！");
        }
        // 判断图形验证码是否存在
        if (imageCodeKeyTemp == null){
            throw new BusinessException("验证码已过期，请重新获取");
        }
        // 判断验证码是否正确
        if(!imageCodeKeyTemp.toString().equalsIgnoreCase(imageCodeValue)){
            throw new BusinessException("验证码错误请重新输入");
        }
    }

    /**
    * @Title: sendCode
    * @Description: 发送验证码
    * @Author: Sheldon
    * @Version: 1.0
    * @Date:  2022/7/10 18:51
    * @Parameters: [businessKey, phone]
    * @Return void
    */
    public void sendCode(String businessKey, String phone){
        String phoneCodeKey = businessKey + phone;
        Object phoneCodeValue = redisTemplate.opsForValue().get(phoneCodeKey);
        String phoneCode = "";
        if (phoneCodeValue == null){
            // 生成新的随机验证码,并赋值给空字符串
            phoneCode = StrUtils.getComplexRandomString(4);
        }else {
            // 分割value得到时间戳，跟现在的时间戳做减法，如果小于1分钟的毫秒数抛出异常
            String[] phoneCodeValueTmp = phoneCodeValue.toString().split(":");
            // 之前存入code时，我们记录的时间戳
            Long oldTime = Long.valueOf(phoneCodeValueTmp[0]);
            // 现在的时间戳
            Long nowTime = System.currentTimeMillis();
            if (nowTime - oldTime < 1*60*1000){
                throw new BusinessException("请一分钟之后再获取！");
            }
            // 将旧的验证码赋值给空字符串
            phoneCode = phoneCodeValueTmp[1];
        }
        // 通过业务键+phone作为key，验证码+时间戳作为value，存入redis，设置为三分钟有效
        String phoneCodeRedis = System.currentTimeMillis() + ":" + phoneCode;
        redisTemplate.opsForValue().set(phoneCodeKey, phoneCodeRedis, 3, TimeUnit.MINUTES);
        // 发送短信验证码
        // SmsUtils.sendCode(phone, "亲，您的验证码是："+ phoneCode);
        System.out.println("----------"+phoneCodeKey);
        System.out.println("======"+redisTemplate.opsForValue().get(phoneCodeKey));
        System.out.println("亲，您的验证码是："+ phoneCode);
    }



    @Override
    public void mailCode(EmailCodeDto emailCodeDto) {
        String email = emailCodeDto.getEmail();
        String imageCodeKey = emailCodeDto.getImageCodeKey();
        String imageCodeValue = emailCodeDto.getImageCodeValue();
        // 参数为空判断
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(imageCodeKey)
                || StringUtils.isEmpty(imageCodeValue)){
            throw new BusinessException("参数不能为空！");
        }
        // 根据电话号码查询该用户
        User user = userMapper.loadByEmail(email);
        if(user != null){
            throw new BusinessException("用户已存在，请直接登录");
        }

        Object imageCodeKeyTemp = redisTemplate.opsForValue().get(imageCodeKey);
        // 判断图形验证码是否存在
        if (imageCodeKeyTemp == null){
            throw new BusinessException("验证码已过期，请重新获取");
        }
        // 判断验证码是否正确
        if(!imageCodeKeyTemp.toString().equalsIgnoreCase(imageCodeValue)){
            throw new BusinessException("验证码错误请重新输入");
        }

        String emailCodeKey = BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_KEY + email;
        Object emailCodeValue = redisTemplate.opsForValue().get(emailCodeKey);
        String emailCode = "";
        if (emailCodeValue == null){
            // 生成新的随机验证码,并赋值给空字符串
            emailCode = StrUtils.getComplexRandomString(4);
        }else {
            // 分割value得到时间戳，跟现在的时间戳做减法，如果小于1分钟的毫秒数抛出异常
            String[] emailCodeValueTmp = emailCodeValue.toString().split(":");
            // 之前存入code时，我们记录的时间戳
            Long oldTime = Long.valueOf(emailCodeValueTmp[0]);
            // 现在的时间戳
            Long nowTime = System.currentTimeMillis();
            if (nowTime - oldTime < 1*60*1000){
                throw new BusinessException("请一分钟之后再获取！");
            }
            // 将旧的验证码赋值给空字符串
            emailCode = emailCodeValueTmp[1];
        }
        // 通过业务键+phone作为key，验证码+时间戳作为value，存入redis，设置为三分钟有效
        String phoneCodeRedis = System.currentTimeMillis() + ":" + emailCode;
        redisTemplate.opsForValue().set(emailCodeKey, phoneCodeRedis, 3, TimeUnit.MINUTES);
        // 发送短信验证码
        // SmsUtils.sendCode(phone, "亲，您的验证码是："+ emailCode);
        System.out.println("----------"+emailCodeKey);
        System.out.println("======"+redisTemplate.opsForValue().get(emailCodeKey));
        System.out.println("亲，您的验证码是："+ emailCode);
    }
}
